package com.laibo.core.test;

import org.apache.commons.io.FileUtils;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.util.MurmurHash;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

public class RedisUtil {
    private static ShardedJedisPool pool;
    private static ShardedJedisPool pool1;
    private static final Charset charset = Charset.forName("UTF-8");
    private static AtomicLong len = new AtomicLong(0);
    private static AtomicInteger count = new AtomicInteger(0);
    private static final MurmurHash murmurHash = new MurmurHash();
    private static final int hashSize = 10000;

    public static void main(String[] args) {
        try {
            String s = FileUtils.readFileToString(new File("C:\\Users\\YouAreJ\\Desktop\\gg"), StandardCharsets.UTF_8);
            String[] split = s.trim().split("\\n+");
            int q0 = 16850944;
            int q1 = 2238241;
            int[] z0 = new int[3];
            int[] z1 = new int[3];
            for(String a : split){
                String[] split1 = a.trim().split("\\s+");
                int kk = Integer.parseInt(split1[0]);
                int or = Integer.parseInt(split1[1]);
                int co = Integer.parseInt(split1[2]);
                if(kk > 3000000){
                    z0[0] += or;
                    z1[0] += co;
                } else {
                    z0[1] += or;
                    z1[1] += co;
                }
            }
            float oop = (float) z0[0] / q0;
            float cop = (float) z1[0] / q1;
            float oocop = (float) z1[0] / z0[0];
            float oop1 = (float) z0[1] / q0;
            float cop1 = (float) z1[1] / q1;
            float oocop1 = (float) z1[1] / z0[1];
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public synchronized static ShardedJedis getJedis() {
        if (pool != null && !pool.isClosed()) {
            return pool.getResource();
        }
        int port = 30426;
        String pass = "";
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMinIdle(20);
        config.setMaxTotal(2000);
        config.setMaxIdle(2000);
        config.setMaxWaitMillis(5000);
        List<JedisShardInfo> list = new ArrayList<>();
        String host = "192.168.7.11";
        for (String h : host.split(",")) {
            JedisShardInfo info = new JedisShardInfo(h, port);
            info.setSoTimeout(1000);
            if (pass.length() > 0) {
                info.setPassword(pass);
            }
            try{
                Class<? extends JedisShardInfo> clz = info.getClass();
                Field declaredField = clz.getDeclaredField("db");
                declaredField.setAccessible(true);
                declaredField.set(info, 0);
                list.add(info);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        pool = new ShardedJedisPool(config, list);
        return pool.getResource();
    }
    public static long sizeOfQueue(String key){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                return jedis.llen(key.getBytes());
            } catch (Exception e){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }
    
    public static void pushQueue(String key,String value){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                jedis.lpush(key.getBytes(), value.getBytes());
                break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static void pushMQueue(String key,byte[]... value){
        int retry = 20;
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                jedis.lpush(key.getBytes(), value);
                break;
            }catch (Exception e){
//                if(-- retry == 0){
//                    return;
//                }
//                System.out.println(key);
//                System.out.println(value);
                e.printStackTrace();
                System.out.println(key);
                System.out.println(Arrays.toString(value[0]));
                try {
                    Thread.sleep(Long.MAX_VALUE);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    
    public static long llen(String key){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                return jedis.llen(key);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static void addSet(String key,String value){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                Long sadd = jedis.sadd(key.getBytes(), value.getBytes());
                break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static void hset(String value){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                int hash = hashMod(value,hashSize);
                Long sadd = jedis.hset(hash + "", value, "");
                break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static void srem(String key,String... value){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                Long sadd = jedis.srem(key, value);
                break;
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static boolean sismember(String key,String value){
        int retry = 0;
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                return jedis.sismember(key,value);
            }catch (Exception e){
                if(++retry > 3){
                    return false;
                }
                e.printStackTrace();
            }
        }
    }
    public static void addMSet(String key,byte[]... value){
        int total = 0;
        int retry = 0;
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                Long sadd = jedis.sadd(key.getBytes(), value);
//                total += sadd;
//                if(++retry > 1){
//                    System.out.println("重试 " + retry);
//                }
                return;
//                if(total == value.length){
//                    return;
//                } else {
////                    System.out.println(value.length - total);
////                    return;
//                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    public static long sizeOfSet(String key){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                return jedis.scard(key.getBytes());
            } catch (Exception e){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }
    
    protected void deleteFromSet(String set, String... docid){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                jedis.srem(set,docid);
                return;
            } catch (Exception e){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }
    
    public static void incr(String key, long value){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                jedis.incrBy(key, value);
                return;
            } catch (Exception e){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }
    
    public static String get(String key){
        while (true){
            try(ShardedJedis jedis = RedisUtil.getJedis()) {
                return jedis.get(key);
            } catch (Exception e){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }
        }
    }
    
    private static int hashMod(String key, int total){
        long hash = hash(key);
        return (int)Math.floorMod(hash, (long)total);
    }

    private static long hash(String key){
        return Math.abs(murmurHash.hash(key));
    }

    public static void deleteKey(String key){
        ShardedJedis jedis = getJedis();
        jedis.del(key);
    }
}
